home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- IsoHex10_4.cpp
- Ernest S. Pazera
- 27JUN2000
- Start a WIN32 Application Workspace, add in this file
- Needs ddraw.lib, and dxguid.lib
- Needs GDICanvas.h/cpp
- Needs DDFuncs.h/cpp
- Needs tileset.h/cpp
- *****************************************************************************/
-
- //////////////////////////////////////////////////////////////////////////////
- //INCLUDES
- //////////////////////////////////////////////////////////////////////////////
- #define WIN32_LEAN_AND_MEAN
-
- #include <windows.h>
- #include "GDICanvas.h"
- #include "ddraw.h"
- #include "DDFuncs.h"
- #include "mmsystem.h"
- #include "TileSet.h"
-
- //////////////////////////////////////////////////////////////////////////////
- //DEFINES
- //////////////////////////////////////////////////////////////////////////////
- //name for our window class
- #define WINDOWCLASS "ISOHEX10"
- //title of the application
- #define WINDOWTITLE "IsoHex 10-4: Reversi"
-
- const int PLAYERONE=0;//black player
- const int PLAYERTWO=1;//white player
- const int PIECEEMPTY=-1;//empty square
- const int PIECEBLACK=0;//black piece
- const int PIECEWHITE=1;//white piece
- const int PIECETRANSIT=2;//animated flip
-
- //game states
- const int GS_NONE=-1;
- const int GS_WAITFORINPUT=0;
- const int GS_NEWGAME=1;
- const int GS_NEXTPLAYER=2;
- const int GS_FLIP=3;
-
- //directions
- const int DIR_NORTH=0;
- const int DIR_NORTHEAST=1;
- const int DIR_EAST=2;
- const int DIR_SOUTHEAST=3;
- const int DIR_SOUTH=4;
- const int DIR_SOUTHWEST=5;
- const int DIR_WEST=6;
- const int DIR_NORTHWEST=7;
- const int DIR_COUNT=8;
-
- //ai levels
- const int AI_HUMAN=0;
- const int AI_RANDOM=1;
- const int AI_GREEDY=2;
- const int AI_MISER=3;
- const int AI_COUNT=4;
-
- //////////////////////////////////////////////////////////////////////////////
- //PROTOTYPES
- //////////////////////////////////////////////////////////////////////////////
- bool Prog_Init();//game data initalizer
- void Prog_Loop();//main game loop
- void Prog_Done();//game clean up
- //save/restore board to backup board
- void SaveBoard();
- void RestoreBoard();
- //game manipulation
- void SetUpBoard();
- void ShowBoard();
- //move
- void ScanForMoves(int plyr);
- bool AnyValidMoves(int plyr);
- bool ValidMove(int plyr,int x,int y);
- bool ValidRun(int plyr,int x,int y,int dir);
- //move x and y in direction
- int DeltaX(int dir);
- int DeltaY(int dir);
- //make a move
- void MakeMove(int plyr,int x, int y);
- void FinishMove(int plyr);
- //ai move functions
- void MakeRandomMove(int plyr);
- void MakeGreedyMove(int plyr);
- void MakeMiserMove(int plyr);
- //score evaulation
- int GetScore(int plyr);
- void ShowScores();
- //last move
- void SetLastMove(int x, int y);
- //show players
- void ShowPlayers();
-
- //////////////////////////////////////////////////////////////////////////////
- //GLOBALS
- //////////////////////////////////////////////////////////////////////////////
- HINSTANCE hInstMain=NULL;//main application handle
- HWND hWndMain=NULL;//handle to our main window
- //IDirectDraw7 Pointer
- LPDIRECTDRAW7 lpdd=NULL;
- //surfaces
- LPDIRECTDRAWSURFACE7 lpddsMain=NULL;
- LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
- //tileset
- CTileSet tsReversi;
-
- //tile information structure
- struct REVERSITILE
- {
- int iTileNum;//base tile number for square
- bool bHilite;//hilited, or not hilited
- int iPiece;//piece occupying square
- bool bLastMove;//last move made
- };
-
- //the board
- REVERSITILE Board[8][8];
- //backup board
- REVERSITILE BackUpBoard[8][8];
- //current player
- int iPlayer=0;
- //counter for animated "flipping" of pieces
- int iAnimation=0;
- //ai level for the players
- int iAILevel[2];
-
- //gamestate
- int iGameState=GS_NONE;
-
- //////////////////////////////////////////////////////////////////////////////
- //WINDOWPROC
- //////////////////////////////////////////////////////////////////////////////
- LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
- {
- //which message did we get?
- switch(uMsg)
- {
- case WM_LBUTTONUP:
- {
- //grab mouse position
- POINT ptMouse;
- ptMouse.x=LOWORD(lParam);
- ptMouse.y=HIWORD(lParam);
-
- //test rectangle
- RECT rcTest;
- //get tile width and height
- int iTileWidth=tsReversi.GetTileList()[0].rcSrc.right-tsReversi.GetTileList()[0].rcSrc.left;
- int iTileHeight=tsReversi.GetTileList()[0].rcSrc.bottom-tsReversi.GetTileList()[0].rcSrc.top;
-
- //calc board rect
- SetRect(&rcTest,(400-iTileWidth*4),(300-iTileHeight*4),(400+iTileWidth*4),(300+iTileHeight*4));
- //point on board?
- if(PtInRect(&rcTest,ptMouse))
- {
- //if we are waiting for input and the ai is "human", check for inside the board
- if((iGameState==GS_WAITFORINPUT) && (iAILevel[iPlayer]==AI_HUMAN))
- {
- //find board position
- int BoardX=(ptMouse.x-rcTest.left)/iTileWidth;
- int BoardY=(ptMouse.y-rcTest.top)/iTileHeight;
-
- //check for a valid square
- if(ValidMove(iPlayer,BoardX,BoardY))
- {
- //make the move
- MakeMove(iPlayer,BoardX,BoardY);
- SetLastMove(BoardX,BoardY);
- iGameState=GS_FLIP;
- }
- }
- //if a game is over, start a new game by clicking on the board
- if(iGameState==GS_NONE)
- {
- iGameState=GS_NEWGAME;
- }
- }
- //check for the AI indicators
- //player one
- SetRect(&rcTest,0,600-iTileHeight,iTileWidth,600);
- //check for mouse in rect
- if(PtInRect(&rcTest,ptMouse))
- {
- iAILevel[PLAYERONE]++;
- iAILevel[PLAYERONE]%=AI_COUNT;
- }
- //player two
- SetRect(&rcTest,iTileWidth,600-iTileHeight,iTileWidth*2,600);
- //check for mouse in rect
- if(PtInRect(&rcTest,ptMouse))
- {
- iAILevel[PLAYERTWO]++;
- iAILevel[PLAYERTWO]%=AI_COUNT;
- }
- }break;
- case WM_KEYDOWN:
- {
- //check for escape key
- if(wParam==VK_ESCAPE)
- {
- DestroyWindow(hWndMain);
- }
-
- //check for F2(new game)
- if(wParam==VK_F2)
- {
- iGameState=GS_NEWGAME;
- }
-
- return(0);//handled message
- }break;
- case WM_DESTROY://the window is being destroyed
- {
-
- //tell the application we are quitting
- PostQuitMessage(0);
-
- //handled message, so return 0
- return(0);
-
- }break;
- case WM_PAINT://the window needs repainting
- {
- //a variable needed for painting information
- PAINTSTRUCT ps;
-
- //start painting
- HDC hdc=BeginPaint(hwnd,&ps);
-
- /////////////////////////////
- //painting code would go here
- /////////////////////////////
-
- //end painting
- EndPaint(hwnd,&ps);
-
- //handled message, so return 0
- return(0);
- }break;
- }
-
- //pass along any other message to default message handler
- return(DefWindowProc(hwnd,uMsg,wParam,lParam));
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- //WINMAIN
- //////////////////////////////////////////////////////////////////////////////
- int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
- {
- //assign instance to global variable
- hInstMain=hInstance;
-
- //create window class
- WNDCLASSEX wcx;
-
- //set the size of the structure
- wcx.cbSize=sizeof(WNDCLASSEX);
-
- //class style
- wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
-
- //window procedure
- wcx.lpfnWndProc=TheWindowProc;
-
- //class extra
- wcx.cbClsExtra=0;
-
- //window extra
- wcx.cbWndExtra=0;
-
- //application handle
- wcx.hInstance=hInstMain;
-
- //icon
- wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
-
- //cursor
- wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
-
- //background color
- wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
-
- //menu
- wcx.lpszMenuName=NULL;
-
- //class name
- wcx.lpszClassName=WINDOWCLASS;
-
- //small icon
- wcx.hIconSm=NULL;
-
- //register the window class, return 0 if not successful
- if(!RegisterClassEx(&wcx)) return(0);
-
- //create main window
- hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
-
- //error check
- if(!hWndMain) return(0);
-
- //if program initialization failed, then return with 0
- if(!Prog_Init()) return(0);
-
- //message structure
- MSG msg;
-
- //message pump
- for(;;)
- {
- //look for a message
- if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
- {
- //there is a message
-
- //check that we arent quitting
- if(msg.message==WM_QUIT) break;
-
- //translate message
- TranslateMessage(&msg);
-
- //dispatch message
- DispatchMessage(&msg);
- }
-
- //run main game loop
- Prog_Loop();
- }
-
- //clean up program data
- Prog_Done();
-
- //return the wparam from the WM_QUIT message
- return(msg.wParam);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //INITIALIZATION
- //////////////////////////////////////////////////////////////////////////////
- bool Prog_Init()
- {
- //seed random number generator
- srand((int)GetTickCount());
-
- //create directdraw interface
- lpdd=LPDD_Create(hWndMain,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
-
- //set display mode(800x600x16)
- lpdd->SetDisplayMode(800,600,16,0,0);
-
- //create primary surface
- lpddsMain=LPDDS_CreatePrimary(lpdd,1);
-
- //get back buffer
- lpddsBack=LPDDS_GetSecondary(lpddsMain);
-
- //load in the tileset
- tsReversi.Load(lpdd,"IsoHex10_4.bmp");
-
- //clear the board
- SetUpBoard();
- //set game state
- iGameState=GS_NONE;
-
- //set initial AI levels
- iAILevel[0]=AI_HUMAN;
- iAILevel[1]=AI_RANDOM;
-
- return(true);//return success
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //CLEANUP
- //////////////////////////////////////////////////////////////////////////////
- void Prog_Done()
- {
- //release primary
- LPDDS_Release(&lpddsMain);
-
- //release ddraw
- LPDD_Release(&lpdd);
- }
-
- //////////////////////////////////////////////////////////////////////////////
- //MAIN GAME LOOP
- //////////////////////////////////////////////////////////////////////////////
- void Prog_Loop()
- {
- //clear out back buffer
- DDBLTFX ddbltfx;
- DDBLTFX_ColorFill(&ddbltfx,0);
- lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL,&ddbltfx);
-
- switch(iGameState)
- {
- case GS_WAITFORINPUT:
- {
- //make move appropriate to the AI
- switch(iAILevel[iPlayer])
- {
- case AI_RANDOM:
- {
- MakeRandomMove(iPlayer);
- }break;
- case AI_GREEDY:
- {
- MakeGreedyMove(iPlayer);
- }break;
- case AI_MISER:
- {
- MakeMiserMove(iPlayer);
- }break;
- }
- }break;
- case GS_NEWGAME:
- {
- //clear the board
- SetUpBoard();
-
- //set player
- iPlayer=PLAYERTWO;
-
- //change gamestate
- iGameState=GS_NEXTPLAYER;
- }break;
- case GS_NEXTPLAYER:
- {
- //scan for moves
- ScanForMoves(iPlayer);
-
- //if no more valid moves, game over
- if((!AnyValidMoves(PLAYERTWO)) && (!AnyValidMoves(PLAYERONE)))
- {
- iGameState=GS_NONE;
- }
- else
- {
- //find if opponent has any moves
- if(AnyValidMoves(1-iPlayer))
- {
- iPlayer=1-iPlayer;
- }
-
- //scan for moves by current player
- ScanForMoves(iPlayer);
-
- //get next move
- iGameState=GS_WAITFORINPUT;
- }
- }break;
- case GS_FLIP:
- {
- switch(iPlayer)
- {
- case PLAYERTWO:
- {
- if(iAnimation==0)
- {
- FinishMove(iPlayer);
- iGameState=GS_NEXTPLAYER;
- }
- else
- {
- iAnimation--;
- }
- }break;
- case PLAYERONE:
- {
- if(iAnimation==14)
- {
- FinishMove(iPlayer);
- iGameState=GS_NEXTPLAYER;
- }
- else
- {
- iAnimation++;
- }
- }break;
- }
- }break;
- }
-
- //show the board
- ShowBoard();
-
- //show the scores
- ShowScores();
-
- //show players
- ShowPlayers();
-
- //flip
- lpddsMain->Flip(NULL,DDFLIP_WAIT);
- }
-
- void SaveBoard()
- {
- //loop through board squares
- for(int x=0;x<8;x++)
- {
- for(int y=0;y<8;y++)
- {
- //save square to backup
- BackUpBoard[x][y]=Board[x][y];
- }
- }
- }
-
- void RestoreBoard()
- {
- //loop through board squares
- for(int x=0;x<8;x++)
- {
- for(int y=0;y<8;y++)
- {
- //restore from backup
- Board[x][y]=BackUpBoard[x][y];
- }
- }
- }
-
- void SetUpBoard()
- {
- //loop through board squares
- for(int x=0;x<8;x++)
- {
- for(int y=0;y<8;y++)
- {
- //setup board square
- Board[x][y].bHilite=false;
- Board[x][y].iTileNum=0;
- Board[x][y].iPiece=PIECEEMPTY;
- Board[x][y].bLastMove=false;
- }
- }
-
- //place initial pieces
- Board[3][3].iPiece=PIECEWHITE;
- Board[4][4].iPiece=PIECEWHITE;
- Board[3][4].iPiece=PIECEBLACK;
- Board[4][3].iPiece=PIECEBLACK;
-
- //place corner markers
- //upper left
- Board[1][1].iTileNum=1;
- Board[2][1].iTileNum=2;
- Board[1][2].iTileNum=3;
- Board[2][2].iTileNum=4;
- //upper right
- Board[5][1].iTileNum=1;
- Board[6][1].iTileNum=2;
- Board[5][2].iTileNum=3;
- Board[6][2].iTileNum=4;
- //lower left
- Board[1][5].iTileNum=1;
- Board[2][5].iTileNum=2;
- Board[1][6].iTileNum=3;
- Board[2][6].iTileNum=4;
- //lower right
- Board[5][5].iTileNum=1;
- Board[6][5].iTileNum=2;
- Board[5][6].iTileNum=3;
- Board[6][6].iTileNum=4;
-
- //save board
- SaveBoard();
- }
-
- void ShowBoard()
- {
- int iTile=0;
- int TileX=0;
- int TileY=0;
- //retrieve tile width and height(assuming all tiles are as wide/high as tile 0)
- int iTileWidth=tsReversi.GetTileList()[0].rcSrc.right-tsReversi.GetTileList()[0].rcSrc.left;
- int iTileHeight=tsReversi.GetTileList()[0].rcSrc.bottom-tsReversi.GetTileList()[0].rcSrc.top;
- //loop through board squares
- for(int y=0;y<8;y++)
- {
- //tile y position
- TileY=y*iTileHeight+(600-iTileHeight*8)/2;
- for(int x=0;x<8;x++)
- {
- //tile x position
- TileX=x*iTileWidth+(800-iTileWidth*8)/2;
-
- //show background
- //base tile
- iTile=Board[x][y].iTileNum;
- //modify for hilite
- if(Board[x][y].bHilite)
- {
- iTile+=5;
- }
- tsReversi.PutTile(lpddsBack,TileX,TileY,iTile);
-
- //show piece
- iTile=Board[x][y].iPiece;
- switch(iTile)
- {
- case PIECEEMPTY:
- {
- //do nothing
- }break;
- case PIECEWHITE:
- {
- //put white piece
- tsReversi.PutTile(lpddsBack,TileX,TileY,10);
- }break;
- case PIECEBLACK:
- {
- //put white piece
- tsReversi.PutTile(lpddsBack,TileX,TileY,24);
- }break;
- case PIECETRANSIT:
- {
- //put transition piece
- tsReversi.PutTile(lpddsBack,TileX,TileY,iAnimation+10);
- }break;
- }
- //hilite last move
- if(Board[x][y].bLastMove)
- {
- tsReversi.PutTile(lpddsBack,TileX,TileY,25);
- }
- }
- }
- }
-
-
- void ScanForMoves(int plyr)
- {
- //loop through board
- for(int x=0;x<8;x++)
- {
- for(int y=0;y<8;y++)
- {
- //check for a valid move
- Board[x][y].bHilite=ValidMove(plyr,x,y);
- }
- }
- }
-
- bool AnyValidMoves(int plyr)
- {
- //scan the board
- for(int x=0;x<8;x++)
- {
- for(int y=0;y<8;y++)
- {
- //a single valid move will return true
- if(ValidMove(plyr,x,y))
- {
- return(true);
- }
- }
- }
- return(false);//didnt find a move, return false
- }
-
- bool ValidMove(int plyr,int x,int y)
- {
- //loop through directions
- for(int dir=DIR_NORTH;dir<DIR_COUNT;dir++)
- {
- //check for a valid run
- if(ValidRun(plyr,x,y,dir))
- {
- //at least one valid run means the move is valid
- return(true);
- }
- }
-
- //default to false
- return(false);
- }
-
- bool ValidRun(int plyr,int x,int y,int dir)
- {
- //set distance to zero
- int dist=0;
- int piece=0;
- for(;;)
- {
- //retrieve the piece
- piece=Board[x][y].iPiece;
-
- switch(dist)
- {
- case 0:
- {
- //if square is not empty, it is not a valid run
- if(piece!=PIECEEMPTY)
- {
- return(false);
- }
- }break;
- case 1:
- {
- //check for bounds
- if(x<0) return(false);
- if(y<0) return(false);
- if(x>7) return(false);
- if(y>7) return(false);
-
- //must have a piece of the opposing side
- if(piece!=(1-plyr))
- {
- return(false);
- }
- }break;
- default:
- {
- //check for bounds
- if(x<0) return(false);
- if(y<0) return(false);
- if(x>7) return(false);
- if(y>7) return(false);
-
- //piece cannot be empty
- if(piece==PIECEEMPTY)
- {
- return(false);
- }
-
- //if piece is of the players color, it is a valid run
- if(piece==plyr)
- {
- return(true);
- }
-
- }break;
- }
- //move the x,y
- x+=DeltaX(dir);
- y+=DeltaY(dir);
- dist++;
- }
- }
-
- int DeltaX(int dir)
- {
- //switch on direction
- switch(dir)
- {
- //directions that require leftward movememnt
- case DIR_NORTHWEST:
- case DIR_WEST:
- case DIR_SOUTHWEST:
- {
- return(-1);
- }break;
- //directions that require rightward movement
- case DIR_NORTHEAST:
- case DIR_EAST:
- case DIR_SOUTHEAST:
- {
- return(1);
- }break;
- }
- return(0);//default to no movement
- }
-
- int DeltaY(int dir)
- {
- //switch on direction
- switch(dir)
- {
- case DIR_NORTHWEST:
- case DIR_NORTH:
- case DIR_NORTHEAST:
- {
- //upward
- return(-1);
- }break;
- case DIR_SOUTHWEST:
- case DIR_SOUTH:
- case DIR_SOUTHEAST:
- {
- //downward
- return(1);
- }break;
- }
- return(0);//default to no movement
- }
-
- void MakeMove(int plyr,int x,int y)
- {
-
- //store valid runs
- bool Run[DIR_COUNT];
- int dir=0;
- for(dir=DIR_NORTH;dir<DIR_COUNT;dir++)
- {
- Run[dir]=ValidRun(plyr,x,y,dir);
- }
-
- //set pieces to transitory state
- int tx;//tx is a temporary x coordinate
- int ty;
- for(dir=DIR_NORTH;dir<DIR_COUNT;dir++)
- {
- //must be a valid run
- if(Run[dir])
- {
- //set first position
- tx=x+DeltaX(dir);
- ty=y+DeltaY(dir);
-
- //while still on an opposing piece
- while(Board[tx][ty].iPiece==(1-plyr))
- {
- //set piece to transit
- Board[tx][ty].iPiece=PIECETRANSIT;
- //update x,y position
- tx+=DeltaX(dir);
- ty+=DeltaY(dir);
- }
- }
- }
-
- //set the appropriate animation value
- switch(plyr)
- {
- case PLAYERTWO:
- {
- //animation value of 14
- iAnimation=14;
- }break;
- case PLAYERONE:
- {
- //animation value of 0
- iAnimation=0;
- }break;
- }
-
- //set initial piece
- Board[x][y].iPiece=plyr;
-
- }
-
- void FinishMove(int plyr)
- {
- //scan board
- for(int x=0;x<8;x++)
- {
- for(int y=0;y<8;y++)
- {
- //if a transit piece
- if(Board[x][y].iPiece==PIECETRANSIT)
- {
- //set to player's piece
- Board[x][y].iPiece=plyr;
- }
- }
- }
- }
-
- void MakeRandomMove(int plyr)
- {
- int x;
- int y;
- //pick a valid, random move
- for(;;)
- {
- //pick random square
- x=rand()%8;
- y=rand()%8;
- //if a valid move, break out of the loop
- if(ValidMove(plyr,x,y)) break;
- }
- //make the move
- MakeMove(plyr,x,y);
- iGameState=GS_FLIP;
- SetLastMove(x,y);
- }
-
- void MakeGreedyMove(int plyr)
- {
- //loop vars
- int x;
- int y;
- //backup the board
- SaveBoard();
- //make an ai array for judging moves
- int AI[8][8];
- int hival=0;
- //loop through board squares
- for(x=0;x<8;x++)
- {
- for(y=0;y<8;y++)
- {
- //restore the board
- RestoreBoard();
- //check for valid move
- if(ValidMove(plyr,x,y))
- {
- //valid move
- MakeMove(plyr,x,y);
- FinishMove(plyr);
- AI[x][y]=GetScore(plyr);
- }
- else
- {
- //non-valid move
- AI[x][y]=0;
- }
- //new high value
- if(AI[x][y]>hival)
- {
- hival=AI[x][y];
- }
- }
- }
- //restore the board
- RestoreBoard();
- //find a square
- for(;;)
- {
- //pick random square
- x=rand()%8;
- y=rand()%8;
- //check against hival
- if(AI[x][y]==hival) break;
- }
- MakeMove(plyr,x,y);
- iGameState=GS_FLIP;
- SetLastMove(x,y);
- }
-
- void MakeMiserMove(int plyr)
- {
- //loop vars
- int x;
- int y;
- //temp x and y
- int tx;
- int ty;
- //backup the board
- SaveBoard();
- //make an ai array for judging moves
- int AI[8][8];
- int loval=0x7FFFFFFF;
- //loop through board squares
- for(x=0;x<8;x++)
- {
- for(y=0;y<8;y++)
- {
- AI[x][y]=0;
- //restore the board
- RestoreBoard();
- //check for valid move
- if(ValidMove(plyr,x,y))
- {
- //weight the moves
- //edges
- if(x==0) AI[x][y]-=2;
- if(x==7) AI[x][y]-=2;
- if(y==0) AI[x][y]-=2;
- if(y==7) AI[x][y]-=2;
- //corners
- if((x==0) && (y==0)) AI[x][y]-=6;
- if((x==7) && (y==0)) AI[x][y]-=6;
- if((x==0) && (y==7)) AI[x][y]-=6;
- if((x==7) && (y==7)) AI[x][y]-=6;
-
- //valid move
- MakeMove(plyr,x,y);
- FinishMove(plyr);
- //loop to count valid moves for opposing player
- for(tx=0;tx<8;tx++)
- {
- for(ty=0;ty<8;ty++)
- {
- //count valid moves
- if(ValidMove(1-plyr,tx,ty))
- {
- AI[x][y]++;
- //edges
- if(tx==0) AI[x][y]+=1;
- if(tx==7) AI[x][y]+=1;
- if(ty==0) AI[x][y]+=1;
- if(ty==7) AI[x][y]+=1;
- //corners
- if((tx==0) && (ty==0)) AI[x][y]+=3;
- if((tx==7) && (ty==0)) AI[x][y]+=3;
- if((tx==0) && (ty==7)) AI[x][y]+=3;
- if((tx==7) && (ty==7)) AI[x][y]+=3;
- }
- }
- }
- }
- else
- {
- //not a valid move
- AI[x][y]=0x7FFFFFFF;
- }
- //new high value
- if(AI[x][y]<loval)
- {
- loval=AI[x][y];
- }
- }
- }
- //restore the board
- RestoreBoard();
- //find a square
- for(;;)
- {
- //pick random square
- x=rand()%8;
- y=rand()%8;
- //check against hival
- if(AI[x][y]==loval) break;
- }
- MakeMove(plyr,x,y);
- iGameState=GS_FLIP;
- SetLastMove(x,y);
- }
-
- int GetScore(int plyr)
- {
- int score=0;
- //loop through board
- for(int x=0;x<8;x++)
- {
- for(int y=0;y<8;y++)
- {
- //if piece belongs to plr, add to score
- if(Board[x][y].iPiece==plyr) score++;
- }
- }
- return(score);
- }
-
- void ShowScores()
- {
- //score and counter
- int score;
- int counter;
- //player one score
- score=GetScore(PLAYERONE);
- //show a column of player one's pieces
- for(counter=0;counter<score;counter++)
- {
- tsReversi.PutTile(lpddsBack,0,4*counter,24);
- }
- //player two score
- score=GetScore(PLAYERTWO);
- //show columns of player two's pieces
- for(counter=0;counter<score;counter++)
- {
- tsReversi.PutTile(lpddsBack,(tsReversi.GetTileList()[0].rcSrc.right-tsReversi.GetTileList()[0].rcSrc.left),4*counter,10);
- }
- }
-
- void SetLastMove(int x, int y)
- {
- //temp x and y for loops
- for(int tx=0;tx<8;tx++)
- {
- for(int ty=0;ty<8;ty++)
- {
- //clear the lastmove
- Board[tx][ty].bLastMove=false;
- }
- }
- //set new last move
- Board[x][y].bLastMove=true;
- }
-
- void ShowPlayers()
- {
- //grab tile width
- int iTileWidth=tsReversi.GetTileList()[0].rcSrc.right-tsReversi.GetTileList()[0].rcSrc.left;
- //grab tile height
- int iTileHeight=tsReversi.GetTileList()[0].rcSrc.bottom-tsReversi.GetTileList()[0].rcSrc.top;
-
- //show player 1
- tsReversi.PutTile(lpddsBack,0,600-iTileHeight,24);
- //show AI level
- tsReversi.PutTile(lpddsBack,0,600-iTileHeight,26+iAILevel[PLAYERONE]);
- //show player 2
- tsReversi.PutTile(lpddsBack,iTileWidth,600-iTileHeight,10);
- //show AI level
- tsReversi.PutTile(lpddsBack,iTileWidth,600-iTileHeight,26+iAILevel[PLAYERTWO]);
- //show current player
- tsReversi.PutTile(lpddsBack,iTileWidth*iPlayer,600-iTileHeight,25);
- }
-